using System;
using GameFramework;
using GameFramework.Fsm;
using LS.Fsm;
using UnityGameFramework.Runtime;

namespace LS.Procedure
{
    public class SceneLoader : ISceneLoaderOwner, IReference
    {
        public event Action<SceneLoader> BeforeLoadingEvent;
        public event Action<SceneLoader> AfterLoadingEvent;
        public event Action<SceneLoader> LoadFinishEvent;
        public event Action<SceneLoader> UpdateProgressEvent;
        
        private float m_Progress = 0;
        private IFsm<SceneLoader> m_Fsm;
        private SceneLoaderState<SceneLoader> m_LoaderState;

        public float Progress => m_Progress;
        public bool IsLoading => m_Fsm?.IsRunning ?? false;
        public bool LoadEnded => m_LoaderState?.IsFinish ?? false;
        public bool LoadSuccess => m_LoaderState?.IsSuccess ?? false;

        public string[] SceneAssetNames { get; set; }
        public bool UnloadCurrentScenes { get; set; } = true;

        public SceneLoader()
        {

        }

        public void Start()
        {
            if (m_Fsm != null && m_Fsm.IsRunning)
            {
                Log.Warning("Scene loader is already running!");
                return;
            }
            
            m_LoaderState = ReferencePool.Acquire<SceneLoaderState<SceneLoader>>();
            m_Fsm = LSEntry.Fsm.CreateFsm(this,
                m_LoaderState
            );
            m_Fsm.Start<SceneLoaderState<SceneLoader>>();
        }

        public void BeforeLoad()
        {
            BeforeLoadingEvent?.Invoke(this);
        }

        public void AfterLoad()
        {
            AfterLoadingEvent?.Invoke(this);
        }

        public void LoadFinish()
        {
            LoadFinishEvent?.Invoke(this);
        }

        public void UpdateProgress(float progress)
        {
            m_Progress = progress;
            UpdateProgressEvent?.Invoke(this);
        }

        public void Clear()
        {
            if (m_Fsm != null)
            {
                LSEntry.Fsm.DestroyFsm(m_Fsm);
                m_Fsm = null;
                m_LoaderState = null;
            }
            m_Progress = 0;
            SceneAssetNames = null;
            UnloadCurrentScenes = true;
            BeforeLoadingEvent = null;
            AfterLoadingEvent = null;
            LoadFinishEvent = null;
            UpdateProgressEvent = null;
        }
    }
}